package com.xdw.addressbookbyjava.slice;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.lxj.xpopup.XPopup;
import com.lxj.xpopup.interfaces.OnSelectListener;
import com.xdw.addressbookbyjava.MyApplication;
import com.xdw.addressbookbyjava.ResourceTable;
import com.xdw.addressbookbyjava.constant.Constant;
import com.xdw.addressbookbyjava.dao.ContactsDao;
import com.xdw.addressbookbyjava.dao.impl.ContactsDaoImpl;
import com.xdw.addressbookbyjava.model.ApiResult;
import com.xdw.addressbookbyjava.model.Contacts;
import com.xdw.addressbookbyjava.provider.ContactsProvider;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.ability.OnClickListener;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.IntentParams;
import ohos.agp.components.*;
import ohos.agp.window.dialog.CommonDialog;
import ohos.agp.window.dialog.IDialog;
import ohos.agp.window.dialog.ToastDialog;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import okhttp3.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class MainAbilitySlice extends AbilitySlice implements Component.ClickedListener {
    public static final String TAG = "MainAbilitySlice";
    private static final HiLogLabel LABEL = new HiLogLabel(HiLog.DEBUG, 0, TAG);
    private Image addContactsBtn;    //添加联系人按钮
    private Image menuBtn;          //菜单按钮
    private List<Contacts> list = new ArrayList<>();    //列表数据源
    private ListContainer listContainer;   //list列表
    private ContactsProvider contactsProvider;    //list列表绑定的provider
    private int currentIndex;   //当前item的索引位
    private TextField nameTf;     //联系人姓名输入框
    private RadioContainer genderRc;    //联系人性别单选框组合容器
    private TextField phoneTf;  //联系人电话号码输入框
    private RadioButton manRb;  //单选按钮，男
    private RadioButton ladyRb; //单选按钮，女
    private ContactsDao contactsDao = new ContactsDaoImpl();

    //定义系统自带的对话框相关的操作start
    private static final int DIALOG_BUTTON_CANCEL = 1;
    private static final int DIALOG_BUTTON_CONFIRM = 2;
    private IDialog.ClickedListener clickedListener = new IDialog.ClickedListener() {
        @Override
        public void onClick(IDialog iDialog, int i) {
            switch (i) {
                case DIALOG_BUTTON_CANCEL:
//                    showToast("对话框取消");
                    iDialog.remove();
                    break;
                case DIALOG_BUTTON_CONFIRM:
//                    showToast("对话框确认");
                    if (list != null && list.size() > currentIndex) {
                        if (MyApplication.DEV_DATA_VERSION == MyApplication.SQLITE_DATA_VERSION) {
                            contactsDao.deleteContacts(list.get(currentIndex).getId()); //从数据库删除联系人
                        }
                        list.remove(currentIndex);  //list数据源中删除该项联系人
                        contactsProvider.notifyDataSetItemRemoved(currentIndex);  //刷新listcontainer显示
                        iDialog.remove();           //删除这里有点小bug，可能是系统问题，这里必须还要在点一下手机页面listcontainer才能刷新显示
                    }
                    break;
            }
        }
    };
    //定义系统自带的对话框相关的操作end

    //定义一个成员变量表示XPopup的构造器对象，用于创建弹出式菜单
    XPopup.Builder builder;
    private static final int EVENT_ID_SUCC=100;  //用于网络请求返回正确数据时子线程与UI主线程间通信
    private static final int EVENT_ID_ERROR=101;  //用于网络请求返回错误数据时子线程与UI主线程间通信
    private static final int EVENT_ID_FAIL=102;  //用于网络异常时子线程与UI主线程间通信
    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        initView();
        initListContainer();

    }

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }

    /**
     * 初始化视图组件以及绑定监听事件
     */
    private void initView() {
        addContactsBtn = (Image) findComponentById(ResourceTable.Id_image_add);
        menuBtn = (Image) findComponentById(ResourceTable.Id_image_menu);
        addContactsBtn.setClickedListener(this);
        // 必须在事件发生前，调用这个方法来监视View的触摸
        builder = new XPopup.Builder(getContext()).watchView(menuBtn);
        menuBtn.setClickedListener(this);
    }

    /**
     * 初始化列表
     */
    private void initListContainer() {
        listContainer = (ListContainer) findComponentById(ResourceTable.Id_list_contacts);
        if (MyApplication.DEV_DATA_VERSION == MyApplication.SQLITE_DATA_VERSION) {
            list = getSqliteData(); //sqlite数据库数据对接
        } else {
            list = getData();   //静态数据对接
        }


        contactsProvider = new ContactsProvider(list, this);
        listContainer.setItemProvider(contactsProvider);
        //设置列表item的点击事件
        listContainer.setItemClickedListener(new ListContainer.ItemClickedListener() {
            @Override
            public void onItemClicked(ListContainer listContainer, Component component, int i, long l) {
//                showToast("第" + i + "行被点击");
                //点击item之后跳转slice页面，并且传递数据
                Intent intent = new Intent();
                intent.setParam("contacts", list.get(i));
                intent.setParam("name", list.get(i).getName());
                present(new ContactsDetailSlice(), intent);
            }
        });

        //设置列表item的长按点击事件，弹出系统自带对话框，点击确认删除联系人
        listContainer.setItemLongClickedListener(new ListContainer.ItemLongClickedListener() {
            @Override
            public boolean onItemLongClicked(ListContainer listContainer, Component component, int i, long l) {
                showToast("item" + i + "长按操作");
                currentIndex = i;
                CommonDialog commonDialog = new CommonDialog(MainAbilitySlice.this);
                commonDialog.setContentText("确认删除该联系人吗？");
                commonDialog.setButton(DIALOG_BUTTON_CANCEL, "取消", clickedListener);
                commonDialog.setButton(DIALOG_BUTTON_CONFIRM, "确定", clickedListener);
                commonDialog.show();
                return false;
            }
        });
    }

    //生成静态的列表数据进行模拟，在对接sqlite或者服务端之后不再使用
    private List<Contacts> getData() {
        List<Contacts> list = new ArrayList<>();
        String[] names = {"克里斯迪亚洛罗纳尔多", "王霜", "梅西", "孙雯", "莱万多夫斯基", "玛塔", "樱木花道", "赤木晴子"};
        for (int i = 0; i <= 7; i++) {
            list.add(new Contacts(names[i], i % 2));
        }
        return list;
    }

    //创建并显示自定义的添加联系人操作的对话框
    private void showAddContactsDialog() {
        CommonDialog commonDialog = new CommonDialog(this);

        Component dialogComponent = LayoutScatter.getInstance(getContext())
                .parse(ResourceTable.Layout_dialog_add_contacts, null, true);

//        commonDialog.setSize(800, 600);     //设置对话框尺寸
        Button btnConfirm = (Button) dialogComponent.findComponentById(ResourceTable.Id_btn_confirm);
        Button btnCancel = (Button) dialogComponent.findComponentById(ResourceTable.Id_btn_cancel);
        nameTf = (TextField) dialogComponent.findComponentById(ResourceTable.Id_tf_name);
        phoneTf = (TextField) dialogComponent.findComponentById(ResourceTable.Id_tf_phone);
        genderRc = (RadioContainer) dialogComponent.findComponentById(ResourceTable.Id_rc_gender);
        manRb = (RadioButton) dialogComponent.findComponentById(ResourceTable.Id_rb_man);
        ladyRb = (RadioButton) dialogComponent.findComponentById(ResourceTable.Id_rb_lady);
        manRb.setChecked(true);
        genderRc.setMarkChangedListener(new RadioContainer.CheckedStateChangedListener() {
            @Override
            public void onCheckedChanged(RadioContainer radioContainer, int i) {

            }
        });
        //采用传统的匿名内部类实现按钮监听器
        btnConfirm.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                new ToastDialog(MainAbilitySlice.this).setText("确定").setDuration(2000).show();
                //list.add(new Contacts("内马尔", 0));
                Contacts contacts = generateContactsFromInput();
                if (MyApplication.DEV_DATA_VERSION == MyApplication.SQLITE_DATA_VERSION) {
                    contactsDao.insertContacts(contacts); //添加到数据库中，当没有对接sqlite而是使用静态数据测试的时候，没有这一步
                }
                list.add(contacts);      //更新list中存储的数据
                contactsProvider.notifyDataChanged();    //更新listcontainer
                commonDialog.remove();
            }
        });

        //采用lamda表达式实现按钮监听器
        btnCancel.setClickedListener((Component component) -> {
            new ToastDialog(MainAbilitySlice.this).setText("取消").setDuration(2000).show();
            commonDialog.remove();
        });


        commonDialog.setContentCustomComponent(dialogComponent);

        commonDialog.show();
    }

    @Override
    public void onClick(Component component) {
        switch (component.getId()) {
            case ResourceTable.Id_image_add:   //添加按钮点击触发
                showAddContactsDialog();
                break;
            case ResourceTable.Id_image_menu:   //菜单按钮点击触发
                //new ToastDialog(MainAbilitySlice.this).setText("菜单功能待完成").setDuration(2000).show();
                //在点击的菜单按钮附件弹出子菜单项，asAttachList方法代表依托受监视的组件进行弹出
                builder.asAttachList(new String[]{"静态数据", "sqlite数据", "服务端数据"}, null,
                        new OnSelectListener() {
                            @Override
                            public void onSelect(int position, String text) {
                                new ToastDialog(MainAbilitySlice.this).setText("click " + text).setDuration(2000).show();
                                switch (position) {
                                    case 0:
                                        list.clear();
                                        list.addAll(getData());
                                        contactsProvider.notifyDataChanged();
                                        break;
                                    case 1:
                                        list.clear();
                                        list.addAll(getSqliteData());
                                        contactsProvider.notifyDataChanged();
                                        break;
                                    case 2:
                                        getServerData();
                                        break;
                                }
                            }
                        })
                        .show();
                break;
        }
    }

    //通过对话框的输入页面输入的数据产生联系人
    private Contacts generateContactsFromInput() {
        Contacts contacts = new Contacts();
        HiLog.info(LABEL, "checked id =" + genderRc.getMarkedButtonId());
        if (genderRc.getMarkedButtonId() == Constant.GENDER_MAN) {
            contacts.setGender(Constant.GENDER_MAN);
        } else {
            contacts.setGender(Constant.GENDER_LADY);
        }
        contacts.setName(nameTf.getText().trim());
        contacts.setPhone(phoneTf.getText().trim());
        return contacts;
    }

    private void showToast(String msg) {
        new ToastDialog(MainAbilitySlice.this).setText(msg).setDuration(2000).show();
    }

    //获取sqlite数据库中的数据，集成sqlite之后调用这个方法取代之前的静态数据方法
    private List<Contacts> getSqliteData() {
        return contactsDao.getAllContacts();
    }

    /**
     * 测试数据库是否生效
     */
    private void testInsertContacts() {
        Contacts contacts = new Contacts();
        contacts.setName("xiadewang");
        contacts.setPhone("13437124333");
        contacts.setGender(0);
        contactsDao.insertContacts(contacts);
    }

    //获取当前主线程的EventRunner，用来存放事件队列
    private EventHandler handler = new EventHandler(EventRunner.current()) {
        protected void processEvent(InnerEvent event) {
            super.processEvent(event);
            if (event == null) {
                return;
            }
            //根据不同的eventId，来进行UI主线程的渲染
            switch (event.eventId){
                case EVENT_ID_FAIL:
                    showToast("网络异常");
                    break;
                case EVENT_ID_ERROR:
                    showToast("服务端返回数据错误");
                    break;
                case EVENT_ID_SUCC:
                    showToast("获取服务端数据成功");
                    //更新联系人列表数据为服务端数据
                    List<Contacts> objectValue = (List<Contacts>) event.object;
                    list.clear();
                    list.addAll(objectValue);
                    contactsProvider.notifyDataChanged();
                    break;
            }
        }
    };

    //通过http请求获取服务端数据
    private void getServerData() {
        String res_url = "/api/getAllContacts"; //请求url资源地址
        OkHttpClient okHttpClient = new OkHttpClient(); //创建一个okHttpClient对象
        //设置网络请求的地址、端口、请求方式
        final Request request = new Request.Builder()
                .url(Constant.SERVER_BASE_URL+res_url)
                .get()//默认就是GET请求，可以不写
                .build();
        //创建用于请求的call对象
        Call call = okHttpClient.newCall(request);
        //在子线程中发起网络请求
        new Thread(new Runnable() {
            @Override
            public void run() {
                call.enqueue(new Callback() {
                    //网络请求失败时的回调
                    @Override
                    public void onFailure(Call call, IOException e) {
                        HiLog.debug(LABEL, "onFailure");
                        handler.sendEvent(EVENT_ID_FAIL);
                    }

                    //服务端成功返回相应的回调
                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        //获取服务端返回的相应数据
                        String responseStr = response.body().string();
                        HiLog.debug(LABEL, "onResponse:" + responseStr);
                        //将响应数据进行json反序列化为我们想要的业务对象
                        ApiResult<List<Contacts>> apiResult = JSON.parseObject(responseStr, new TypeReference<ApiResult<List<Contacts>>>() {
                        });
                        //对返回数据的code识别码进行判断
                        if (apiResult.getCode() == ApiResult.SUCCESS) {
                            //通过handler发送数据进行多线程间通信
                            handler.sendEvent(InnerEvent.get(EVENT_ID_SUCC, apiResult.getData()));
                        } else {
                            //通过handler发送数据进行多线程间通信
                            handler.sendEvent(EVENT_ID_ERROR);
                        }
                    }
                });
            }
        }).start();

    }
}
